//---------------------------------------------------------------------------
// Sword3 Engine (c) 1999-2000 by Kingsoft
//
// File:	FileStream.h
// Date:	2000.08.08
// Code:	WangWei(Daphnis)
// Desc:	Header File
//---------------------------------------------------------------------------
#ifndef _K_FILE_
#define _K_FILE_

#define SEEK_ERROR		0xFFFFFFFF

namespace krt
{
	KRUNTIME_API void ForceDirectory(const char *dir);

	template<class T>
	size_t FindLastChar1(
		const T *str, 
		size_t MaxLen, 
		const T CharToFind, 
		size_t *len)
	{
		size_t i, p = 0;

		for(i = 0; i < MaxLen; ++i)
		{
			if (0 == str[i])
				break;

			if (CharToFind == str[i])
				p = i;
		}

		if (len)
		*len = i;
		return p;
	}

	template<class T>
	size_t FindLastChar2(
		const T *str, 
		size_t MaxLen, 
		const T char1, 
		const T char2,
		size_t *len)
	{
		size_t i, p = 0;

		for(i = 0; i < MaxLen; ++i)
		{
			if (0 == str[i])
				break;

			if (char1 == str[i] || char2 == str[i])
				p = i;
		}

		if (len)
			*len = i;

		return p;
	}

	template<class T>
	void ExtractPathInfo(
		const T *FullName, 
		size_t FullLength, 
		T *PathName, 
		T *FileName)
	{
		size_t len, p;

		p = FindLastChar2(FullName, FullLength, '\\', '/', &len);

		if (0 == p)
		{
			if (PathName)
			{
				memcpy(PathName, FullName, len * sizeof(T));
				PathName[len] = PATH_DELIMITER;	
				PathName[len + 1] = 0;
			}
		
			if (FileName)
			{
				memcpy(FileName, FullName, len * sizeof(T));
				FileName[len] = PATH_DELIMITER;
				FileName[len + 1] = 0;
			}
		}
		else
		{
			if (PathName)
			{
				memcpy(PathName, FullName, (p + 1) * sizeof(T));
				PathName[p + 1] = 0;
			}
			
			if (FileName)
			{
				memcpy(FileName, FullName + (p + 1), (len - p) * sizeof(T));
				FileName[len - p] = 0;
			}
		}
	}

	template<class T>
	size_t ExtractFilePath(const T *FullName, size_t FullLength, T *PathName)
	{
		size_t len, p;

		p = FindLastChar2(FullName, FullLength, '\\', '/', &len);

		if (0 == p)
		{
			memcpy(PathName, FullName, len * sizeof(T));
			PathName[len] = PATH_DELIMITER;
			PathName[len + 1] = 0;
			return (len + 1);
		}
		else
		{
			memcpy(PathName, FullName, (p + 1) * sizeof(T));
			PathName[p + 1] = 0;
			return (p + 1);
		}
	}

	template<class T>
	size_t ExtractFileExt(const T *FileName, size_t FullLength, T *FileExt)
	{
		size_t len, p = 0;

		p = FindLastChar1(FullName, FullLength, '.', &len);

		if (0 == p)
		{
			FileExt[0] = 0;
			return 0;
		}
		else
		{
			memcpy(FileExt, FullName + (p + 1), (i - p) * sizeof(T));
			FileExt[i - p] = 0;
			return (i - p);
		}	
	}

	template<class T>
	size_t ExtractFileName(
		const T *FullName, 
		size_t FullLength, 
		T *FileName)
	{
		size_t len, p;

		p = FindLastChar2(FullName, FullLength, '\\', '/', &len);

		if (0 == p)
		{
			memcpy(FileName, FullName, len * sizeof(T));
			FileName[len] = 0;
			return len;
		}
		else
		{
			memcpy(FileName, FullName + (p + 1), (len - p) * sizeof(T));
			FileName[len - p] = 0;
			return (len - p);
		}	
	}

	template<class T>
	size_t DeleteFileExt(T *FileName, size_t FullLength)
	{
		size_t len, p = 0;

		p = FindLastChar1(FileName, FullLength, '.', &len);

		if (0 == p)
			return len;
		else
		{
			FileName[p] = 0;
			return p;
		}	
	}

	class KRUNTIME_CLASS FileStream: public stream
	{
	private:
		FILE *m_hFile;	
	public:
		typedef enum{
			fmOpenRead,
			fmOpenReadWrite,
			fmCreate
		}FileMode;

		FileStream();
		~FileStream();

		BOOL open(PCSTR FileName, FileMode mode);
		BOOL open(PCWSTR FileName, FileMode mode);
		void close();

		virtual void SetEnd();
		virtual size_type seek(offset_type offset, SeekOrigin origin);
		virtual size_t read(void* buf, size_t BufSize);
		virtual size_t write(const void* buf, size_t BufSize);	
	};
}

//---------------------------------------------------------------------------
#endif	//_K_FILE_
